package fr.mywiki.business.structure;

import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import javax.ejb.FinderException;

import fr.mywiki.business.account.AccountLite;
import fr.mywiki.model.ejbAdapter.DataController;
import fr.mywiki.model.ejbAdapter.Value;
import fr.mywiki.model.queries.DatabaseAdapter;
import fr.mywiki.model.queries.ResultList;

public class StructureLite extends Value {
	private static final long serialVersionUID = 1L;

	/** The type of this object */
	public static final String TYPE_ENT = "structure";
	
	/* The fields constants */
	public static final String FIELD_NAME = "name";
	public static final String FIELD_STRUCTURE_MODEL = "structure_model";
	
	/* The links constants */
	public static final String LINK_CHILD_TO_PARENT = "parent_id";
	public static final String LINK_PARENT_TO_CHILDREN = "parent_to_children"; // Virtual
	public static final String LINK_ACCOUNT_STRUCTURE = AccountLite.LINK_ACCOUNT_STRUCTURE;
	
	private static final String FULLNAME_SEP = "/";
	
	/* The fields */
	/** The name of this structure element */
	private String name;
	/** The structure model of this branch of the structure */
	private String structureModel;
	
	public String getTypeEnt() {
		return TYPE_ENT;
	}
	
	public Object get(String attName) {
		if (FIELD_NAME.equals(attName))
			return getName();
		if (FIELD_STRUCTURE_MODEL.equals(attName))
			return getStructureModel();
		return null;
	}

	public void set(String attName, Object value) {
		if (FIELD_NAME.equals(attName))
			setName((String) value);
		else if (FIELD_STRUCTURE_MODEL.equals(attName))
			setStructureModel((String) value);
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getStructureModel() {
		return structureModel;
	}

	public void setStructureModel(String a_structureModel) {
		structureModel = a_structureModel;
	}
	
	/**
	 * Retrieves the parent of this element via SQL.
	 * 
	 * @return a <code>StructureLite</code> object.
	 */
	protected StructureLite getSqlParent() throws SQLException, RemoteException {
		String sql = "SELECT " + LINK_CHILD_TO_PARENT + " FROM " + TYPE_ENT
				+ " WHERE id=" + getId().toString();
		ResultList result = DatabaseAdapter.executeSelectQuery(sql);
		Long parentId = (Long) result.getRecord(0) [0];
		if (parentId != null)
			return (StructureLite) DataController.getValue(parentId,
					StructureLite.TYPE_ENT);
		return null;
	}
	
	/**
	 * Retrieves the children of this element via SQL.
	 * 
	 * @return a <code>Collection</code> of <code>StructureLite</code> objects.
	 */
	protected Collection getSqlChildren() throws SQLException, RemoteException {
		Collection children = new ArrayList();
		String sql = "SELECT id FROM " + TYPE_ENT + " WHERE "
				+ LINK_CHILD_TO_PARENT + "=" + getId().toString();
		ResultList result = DatabaseAdapter.executeSelectQuery(sql);
		for(int i=0;i<result.getRecordsCount();i++) {
			Long childId = (Long) result.getRecord(i) [0];
			StructureLite child = (StructureLite) DataController.getValue(childId,StructureLite.TYPE_ENT);
			children.add(child);
		}
		return children;
	}
	
	/**
	 * Returns true if this structure element has no parent.
	 * 
	 * @return true iif this element is linked to nothing by parent_id link.
	 */
	public boolean hasParent() throws RemoteException, FinderException{
		return StructureManager.getParent(this) == null ? false : true;
	}
	
	/**
	 * Returns the full name of this structure element. The full name is the
	 * complete path to access it, the last element of the path being the
	 * structure itself, each element separated from the other by "/". The root
	 * object is not displayed.
	 * 
	 * @return a String object.
	 */
	public String getFullName() throws RemoteException, FinderException {
		if(!hasParent())
			return getName();
		return StructureManager.getParent(this).getFullName() + FULLNAME_SEP
				+ getName();
	}
}
